#include "Window.h"			// Header File For Window Manager
#include "Renderer.h"
#include "ProjectHeader.h"
#include "SceneMan.h"
#include <stdlib.h>

void QuitHandler(UINT msg, WPARAM wParam, LPARAM lParam);	// Forward Declaration of QuitHandler

HINSTANCE		hInstance;									// Holds The Instance Of the Application	
Renderer		RenderMan;									// Creates an instance of the Renderer class
SceneMan SMTest;
DrawEvent_delegate		TileDraw_d	(	&SMTest,		&SceneMan::BuildDisplayList);
OpenGLInit_delegate		GLInit_d	(	&RenderMan,		&Renderer::InitGL);		
ResizeEvent_delegate	Resize_d	(	&RenderMan,		&Renderer::ReSizeGLScene);
OpenGLWindow	GLWindow(hInstance, GLInit_d, Resize_d);	// Creates an instance of the OpenGLWindow class
bool	done				=false;							// When false, the program exits the game loop
bool	fullscreen			=true;							// holds the fullscreen state; default fullscreen
char *	windowTitleString	="NeHe DIY OpenGL SDK";			// Holds The Title Of The Window
int		returnValue			=0;								// Allows global functions to set the return value for Main, in case of errors

// Event Handlers
void KeyHandler		(UINT msg, WPARAM wParam, LPARAM lParam)		// Handles keypress events
{
	if (OpenGLWindow::keys[VK_ESCAPE])						// Was ESC Pressed?
	{
		done=TRUE;											// ESC Signalled A Quit
		return;
	}
	if (OpenGLWindow::keys[VK_F1])							// Is F1 Being Pressed?
	{
		OpenGLWindow::keys[VK_F1]=FALSE;					// If So Make Key FALSE
		GLWindow.KillGLWindow();							// Kill Our Current Window
		fullscreen = !fullscreen;							// Toggle Fullscreen / Windowed Mode
		// Recreate Our OpenGL Window							
		if (!GLWindow.CreateGLWindow(windowTitleString,640,480,16,fullscreen))
		{
			done = true;
			returnValue = 1;
		}
		RenderMan.ReSizeGLScene(640, 480);						// Need to call this because CreateGLWindow doesn't
		return;
	}
	if (OpenGLWindow::keys['L'])	//if L is being pressed...
	{
		OpenGLWindow::keys['L'] = FALSE;
		RenderMan.toggleLight();
		return;
	}
	if (OpenGLWindow::keys['B'])
	{
		OpenGLWindow::keys['L'] = FALSE;
		RenderMan.toggleBlend();
		return;
	}
	if(OpenGLWindow::keys['W'])
	{
		OpenGLWindow::keys['W'] = FALSE;
		RenderMan.depth += 1;
		return;
	}
	if(OpenGLWindow::keys['A'])
	{
		OpenGLWindow::keys['A'] = FALSE;
		RenderMan.xView += 1;
		return;
	}
	if(OpenGLWindow::keys['S'])
	{
		OpenGLWindow::keys['S'] = FALSE;
		RenderMan.depth -= 1;
		return;
	}
	if(OpenGLWindow::keys['D'])
	{
		OpenGLWindow::keys['D'] = FALSE;
		RenderMan.xView -= 1;
		return;
	}
}



void QuitHandler	(UINT msg, WPARAM wParam, LPARAM lParam)
{
	done = true;
	returnValue = 0;
}
// Main
int WINAPI WinMain(	HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG		msg;									// Windows Message Structure
	
	// Ask The User Which Screen Mode They Prefer
	if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
	{
		fullscreen=false;							// Windowed Mode
	}
	// Create Our OpenGL Window
	if (!GLWindow.CreateGLWindow(windowTitleString,640,480,16,fullscreen))
	{
		return 0;									// Quit If Window Was Not Created
	}


	//SMTest.xSize = 1; SMTest.ySize = 1;
	//SMTest.CubeMap.resize(4); for(int i = 0; i < 4; i++){SMTest.CubeMap[i].resize(2);}
	//SMTest.Cubes.resize(1); SMTest.Cubes[0].Drawable = true; 
	//SMTest.Cubes[0].Texture[0] = 0; 
	//SMTest.Cubes[0].Texture[1] = 1; 
	//SMTest.Cubes[0].Texture[2] = 2; 
	//SMTest.Cubes[0].Texture[3] = 3; 
	//SMTest.Cubes[0].Texture[4] = 4; 
	//SMTest.Cubes[0].Texture[5] = 5; 
	RenderMan.RegisterDraw(TileDraw_d, STATIC);

	Callback_delegate KeyHandlerDelegate(&KeyHandler);				//These create temporary FastDelegates for callbacks
																	//constructor syntax for static functions is (&Function)
	GLWindow.registerEvent(KeyHandlerDelegate, WM_KEYDOWN);			//if these where member functions,
																	//It'd be (&instance, &class::function)

	while(!done)									// Loop That Runs While done=FALSE
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	// Is There A Message Waiting?
		{
			if (msg.message==WM_QUIT)				// Have We Received A Quit Message?
			{
				done=TRUE;							// If So done=TRUE
			}
			else									// If Not, Deal With Window Messages
			{
				TranslateMessage(&msg);				// Translate The Message
				DispatchMessage(&msg);				// Dispatch The Message
			}
		}
		else										// If There Are No Messages
		{
			// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
			if (GLWindow.active)								// Program Active?
			{
					RenderMan.DrawGLScene();					// Draw The Scene
					GLWindow.SwapWindowBuffers();				// Double Buffered ;)6
			}
		}
	}

	// Shutdown
	GLWindow.KillGLWindow();									// Kill The Window
	if(returnValue){return returnValue;}						// Return returnValue if it's been set
	else return(msg.wParam);									// Otherwise, return the 
}